package com.os.view;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

import com.os.model.*;
import com.os.model.File;
import com.os.util.FATUtil;
import com.os.util.FileType;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 * @author ZZH-LDX
 * @version: 1.0
 */
public class MainView {

	/**
	 * 读取磁盘信息文件路径 disk.txt 文件模拟磁盘
	 */
	private static final String DURATION_PATH = "src/main/resources/disk.txt";

	/**
	 * 文件分配表
	 */
	private FAT fat;

	/**
	 * 当前选中的磁盘块
	 */
	private int index;

	/**
	 * 磁盘块列表
	 */
	private List<DiskBlock> blockList;

	/**
	 * 当前路径
	 * 根据这个进行创建文件和文件夹、打开文件、删除文件等操作
	 */
	private String recentPath;

	/**
	 * 文件路径映射表 用于快速找到对应的TreeItem
	 */
	private Map<Path, TreeItem<String>> pathMap;

	/**
	 * 场景
	 */
	private Scene scene;

	/**
	 * Box布局组件
	 */
	private HBox workBox, mainBox;
	private VBox rightBox, fullBox,openTablevBox;

	private FlowPane flowPane;//文件夹内容展示区域
	private Label[] icons;

	private HBox locBox;
	private Label locLabel;
	private TextField locField;
	private Button gotoButton, backButton;

	private TreeView<String> treeView;
	private TreeItem<String> rootNode, recentNode;

	private TableView<DiskBlock> blockTable;
	private TableView<File> openedTable;
	private ObservableList<DiskBlock> dataBlock;
	private ObservableList<File> dataOpened;

	private ContextMenu contextMenu, contextMenu2,contextMenu3;
	private MenuItem createFileItem, createFolderItem, openItem, renameItem, delItem, propItem,renameItem2, delItem2, propItem2,readWriteOpenItem,readOnlyOpenItem;


	public MainView(Stage stage) {
		pathMap = new HashMap<Path, TreeItem<String>>();

//		InputStream inputStream = getClass().getClassLoader().getResourceAsStream("disk.txt");
//		InputStream inputStream = new FileInputStream(DURATION_PATH);

		// 读取disk.txt文件 初始化磁盘信息 构建FAT对象
		try (InputStream inputStream = new FileInputStream(DURATION_PATH);
			 ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
			fat = (FAT) objectInputStream.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (fat == null) {
			fat = new FAT();
		}
		recentPath = "C:";
		initFrame(stage);
	}

	/**
	 * 初始化框架
	 * @param stage
	 */
	private void initFrame(Stage stage) {

		flowPane = new FlowPane();
		flowPane.setPrefSize(700, 100);
		flowPane.setStyle("-fx-background-color: #f1dffa;" + "-fx-border-color: #ffffff;" + "-fx-border-width:0.5px;");
		flowPane.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent me) -> {
			if (me.getButton() == MouseButton.SECONDARY && !contextMenu2.isShowing()&& !contextMenu3.isShowing()) {
				contextMenu.show(flowPane, me.getScreenX(), me.getScreenY());
			} else {
				contextMenu.hide();
			}
		});



		initContextMenu();
		menuItemSetOnAction();

		initTopBox();
		initTables();
		initTreeView();

		Text text = new Text("文件分配表FAT");
		text.setStyle("-fx-font-size: 20px;" + "-fx-font-weight: bold;" + "-fx-text-fill: #1e90ff;");
		rightBox = new VBox(text, blockTable);
		rightBox.setAlignment(Pos.TOP_CENTER);
		VBox.setMargin(text, new Insets(5, 0, 10, 0));
		VBox.setVgrow(blockTable, Priority.ALWAYS);
		rightBox.setBackground(new Background(new BackgroundFill(javafx.scene.paint.Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)));
		// 创建一个只包含上边框的 Border 对象
		Border border1 = new Border(new BorderStroke(Color.web("#e9e9e9"),
				BorderStrokeStyle.SOLID,
				null,
				new BorderWidths(0, 0, 0, 1)));
		rightBox.setBorder(border1);


		workBox = new HBox(flowPane, rightBox);
		workBox.setPrefHeight(500);
		mainBox = new HBox(treeView, workBox);
		openTablevBox = new VBox();
		Text openText = new Text("已打开的文件");
		openText.setStyle("-fx-font-size: 20px;" + "-fx-font-weight: bold;" + "-fx-text-fill: #1e90ff;");
		openTablevBox.getChildren().addAll(openText,openedTable);
		openTablevBox.setAlignment(Pos.TOP_CENTER);
		openTablevBox.setSpacing(10);
		VBox.setMargin(openText, new Insets(5, 0, 0, 0));
		openTablevBox.setBackground(new Background(new BackgroundFill(javafx.scene.paint.Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)));
		// 创建一个只包含上边框的 Border 对象
		Border border = new Border(new BorderStroke(Color.web("#e9e9e9"),
				BorderStrokeStyle.SOLID,
				null,
				new BorderWidths(1, 0, 0, 0)));
		openTablevBox.setBorder(border);


		fullBox = new VBox(locBox, mainBox,openTablevBox);
		fullBox.setPrefSize(1300, 700);

		scene = new Scene(fullBox);
		scene.getStylesheets().add(getClass().getResource("/css/menu.css").toExternalForm());
		stage.setScene(scene);
		stage.setResizable(false);// 设置窗口大小不可变
		stage.getIcons().add(new Image(FATUtil.ICO));// 设置图标
		stage.setTitle("模拟磁盘文件系统");
		stage.show();
		// 关闭窗口时保存磁盘信息 编码格式为UTF-8

		stage.setOnCloseRequest(e -> {
			if (!fat.getOpenedFiles().isEmpty()) {
				// 弹出提示弹窗告知用户有文件未关闭
				Alert alert = new Alert(AlertType.ERROR);
				alert.setHeaderText(null);
				alert.setContentText("还有文件未关闭，请先关闭文件再尝试关闭系统。");
				alert.showAndWait();
				e.consume(); // 取消窗口关闭操作
			}

			try (FileOutputStream fileOutputStream = new FileOutputStream(DURATION_PATH);
				 ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) {
				System.out.println("writing");
				for (int i = 0; i < blockList.size(); i++) {
					DiskBlock thisBlock = blockList.get(i);
					if (thisBlock.getObject() instanceof Folder) {
						continue;
					}
					((File) thisBlock.getObject()).setOpened(false);
				}
				objectOutputStream.writeObject(fat);
			} catch (FileNotFoundException e1) {
				e1.printStackTrace();
			} catch (IOException e2) {
				e2.printStackTrace();
			}
		});
	}

	/**
	 * 初始化右键菜单
	 */
	private void initContextMenu() {
		createFileItem = new MenuItem("新建文件");
		createFolderItem = new MenuItem("新建文件夹");

		openItem = new MenuItem("打开");
		delItem = new MenuItem("删除");
		renameItem = new MenuItem("重命名");
		propItem = new MenuItem("属性");


		readOnlyOpenItem = new MenuItem("只读");
		readWriteOpenItem = new MenuItem("读写");
		delItem2 = new MenuItem("删除");
		renameItem2 = new MenuItem("重命名");
		propItem2 = new MenuItem("属性");

		// 右键菜单针对空白区域 进行 新建文件、文件夹
		contextMenu = new ContextMenu(createFileItem, createFolderItem);

		// 右键菜单针对文件 进行 打开、删除、重命名、属性
		contextMenu2 = new ContextMenu(openItem, delItem, renameItem, propItem);

		// 右键菜单针对文件夹 进行 打开、删除、重命名、属性
		contextMenu3 = new ContextMenu(readOnlyOpenItem,readWriteOpenItem, delItem2, renameItem2, propItem2);


		// 加载 CSS 样式
		// 你可以设置每个菜单项的样式，例如：
		for (MenuItem item : contextMenu.getItems()) {
			item.getStyleClass().add("menu-item");
		}
		for (MenuItem item : contextMenu2.getItems()) {
			item.getStyleClass().add("menu-item");
		}
		for (MenuItem item : contextMenu3.getItems()) {
			item.getStyleClass().add("menu-item");
		}
	}

	/**
	 * 绑定菜单选项的监听事件
	 */
	private void menuItemSetOnAction() {
		// 创建 文件 菜单选项事件
		createFileItem.setOnAction(ActionEvent -> {
			// 创建文件 并返回 fat 表中对应的磁盘块号 默认文件类型为TXT
			CreateNameView createNameView = new CreateNameView(false);

			createNameView.setFileNameCallback(fileName -> {
				System.out.println("获取到的文件名是: " + fileName);
				// 在这里可以进行后续针对获取到的文件名的处理逻辑
				if (fileName.isEmpty()){
					return;
				}
				// 进行分割获取后缀
				String suffix = fileName.split("\\.")[1];
				int no = FATUtil.ERROR;
				if (suffix.equals("txt")){
					no = fat.createFile(recentPath, FileType.TXT,fileName);
				}else if (suffix.equals("jpg")){
					no = fat.createFile(recentPath, FileType.JPG,fileName);
				}else if (suffix.equals("png")){
					no = fat.createFile(recentPath, FileType.PNG,fileName);
				}else if (suffix.equals("pdf")){
					no = fat.createFile(recentPath, FileType.PDF,fileName);
				}else if (suffix.equals("doc")){
					no = fat.createFile(recentPath, FileType.DOC,fileName);
				}else if (suffix.equals("docx")){
					no = fat.createFile(recentPath, FileType.DOCX,fileName);
				}else if (suffix.equals("xlsx")){
					no = fat.createFile(recentPath, FileType.XLSX,fileName);
				}
				if (no == FATUtil.ERROR) {
					Alert alert = new Alert(AlertType.ERROR);
					alert.setHeaderText("磁盘容量已满，无法创建");
					alert.showAndWait();
				} else {
					// 刷新界面
					flowPane.getChildren().removeAll(flowPane.getChildren());
					addIcon(fat.getBlockList(recentPath), recentPath);
				}
			});
		});

		// 创建 文件夹 菜单选项事件
		createFolderItem.setOnAction(ActionEvent -> {
			// 创建文件夹并返回编号|磁盘块号
			int no = fat.createFolder(recentPath);
			if (no == FATUtil.ERROR) {
				Alert alert = new Alert(AlertType.ERROR);
				alert.setHeaderText("磁盘容量已满，无法创建");
				alert.showAndWait();
			} else {
				Folder newFolder = (Folder) fat.getBlock(no).getObject();
				Path newPath = newFolder.getPath();
				flowPane.getChildren().removeAll(flowPane.getChildren());
				addIcon(fat.getBlockList(recentPath), recentPath);
				addNode(recentNode, newPath);
			}
		});
		// 打开 文件 菜单选项事件
		openItem.setOnAction(ActionEvent -> onOpen());
		readWriteOpenItem.setOnAction(ActionEvent -> onFlagOpen(FATUtil.FLAGWRITE));
		readOnlyOpenItem.setOnAction(ActionEvent -> onFlagOpen(FATUtil.FLAGREAD));



		// 删除 文件 菜单选项事件
		delItem.setOnAction(ActionEvent -> {
			DiskBlock thisBlock = blockList.get(index);
			// 检查当前磁盘块是否打开状态
			if (fat.isOpenedFile(thisBlock)) {
				Alert alert = new Alert(AlertType.ERROR);
				alert.setHeaderText(null);
				alert.setContentText("文件未关闭");
				alert.showAndWait();
			} else {
				new DelView(thisBlock, fat, MainView.this);
				flowPane.getChildren().removeAll(flowPane.getChildren());
				addIcon(fat.getBlockList(recentPath), recentPath);
			}
		});

		delItem2.setOnAction(ActionEvent -> {
			DiskBlock thisBlock = blockList.get(index);
			// 检查当前磁盘块是否打开状态
			if (fat.isOpenedFile(thisBlock)) {
				Alert alert = new Alert(AlertType.ERROR);
				alert.setHeaderText(null);
				alert.setContentText("文件未关闭");
				alert.showAndWait();
			} else {
				new DelView(thisBlock, fat, MainView.this);
				flowPane.getChildren().removeAll(flowPane.getChildren());
				addIcon(fat.getBlockList(recentPath), recentPath);
			}
		});

		renameItem.setOnAction(ActionEvent -> {
			DiskBlock thisBlock = blockList.get(index);
			new RenameView(thisBlock, fat, icons[index], pathMap);
		});

		renameItem2.setOnAction(ActionEvent -> {
			DiskBlock thisBlock = blockList.get(index);
			new RenameView(thisBlock, fat, icons[index], pathMap);
		});

		propItem.setOnAction(ActionEvent -> {
			DiskBlock thisBlock = blockList.get(index);
			new PropertyView(thisBlock, fat, icons[index], pathMap);
		});

		propItem2.setOnAction(ActionEvent -> {
			DiskBlock thisBlock = blockList.get(index);
			new PropertyView(thisBlock, fat, icons[index], pathMap);
		});

	}

	private void initTopBox() {
		locLabel = new Label("当前目录：");
		locLabel.setStyle("-fx-font-weight: bold;" + "-fx-font-size: 16px");

		locField = new TextField("C:");
		locField.setPrefWidth(400);

		backButton = new Button();
		backButton.setOnAction(ActionEvent -> {
			System.out.println(recentPath);
			Path backPath = fat.getPath(recentPath).getParent();
			if (backPath != null) {
				List<DiskBlock> blocks = fat.getBlockList(backPath.getPathName());
				flowPane.getChildren().removeAll(flowPane.getChildren());
				addIcon(blocks, backPath.getPathName());
				recentPath = backPath.getPathName();
				recentNode = pathMap.get(backPath);
				locField.setText(recentPath);
			}
		});
		backButton.setGraphic(new ImageView(FATUtil.BACK_IMG));
		backButton.setStyle("-fx-background-color: #ffffff;");
		backButton.setOnMouseEntered(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				backButton.setStyle("-fx-background-color: #1e90ff;");
			}
		});
		backButton.setOnMouseExited(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				backButton.setStyle("-fx-background-color: #ffffff;");
			}
		});

		gotoButton = new Button();
		gotoButton.setOnAction(ActionEvent -> {
			String textPath = locField.getText();
			Path gotoPath = fat.getPath(textPath);
			if (gotoPath != null) {
				List<DiskBlock> blocks = fat.getBlockList(textPath);
				flowPane.getChildren().removeAll(flowPane.getChildren());
				addIcon(blocks, textPath);
				recentPath = textPath;
				recentNode = pathMap.get(gotoPath);
			} else {
				Alert alert = new Alert(AlertType.ERROR);
				alert.setContentText("目录不存在");
				alert.setHeaderText(null);
				alert.show();
				locField.setText(recentPath);
			}
		});
		gotoButton.setGraphic(new ImageView(FATUtil.FORWARD_IMG));
		gotoButton.setStyle("-fx-background-color: #ffffff;");
		gotoButton.setOnMouseEntered(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				gotoButton.setStyle("-fx-background-color: #1e90ff;");
			}
		});
		gotoButton.setOnMouseExited(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				gotoButton.setStyle("-fx-background-color: #ffffff;");
			}
		});

		locBox = new HBox(locLabel, locField,backButton, gotoButton);
		locBox.setAlignment(Pos.CENTER_LEFT);
		locBox.setStyle("-fx-background-color: #ffffff;" + "-fx-border-color: #d3d3d3;" + "-fx-border-width:0.5px;");
		locBox.setSpacing(10);
		locBox.setPadding(new Insets(5, 5, 5, 5));

	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void initTables() {
		blockTable = new TableView<DiskBlock>();
		openedTable = new TableView<File>();

		blockTable
				.setStyle("-fx-background-color: #ffffff;" + "-fx-border-color: #d3d3d3;" + "-fx-border-width:0.5px;");
		openedTable
				.setStyle("-fx-background-color: #ffffff;" + "-fx-border-color: #d3d3d3;" + "-fx-border-width:0.5px;");

		dataBlock = FXCollections.observableArrayList(fat.getDiskBlocks());
		dataOpened = fat.getOpenedFiles();

		TableColumn noCol = new TableColumn("磁盘块");
		noCol.setCellValueFactory(new PropertyValueFactory<DiskBlock, String>("noP"));
		noCol.setSortable(false);
		noCol.setMinWidth(80);
		noCol.setResizable(false);

		TableColumn indexCol = new TableColumn("索引");
		indexCol.setCellValueFactory(new PropertyValueFactory<DiskBlock, String>("indexP"));
		indexCol.setSortable(false);
		indexCol.setMaxWidth(50);
		indexCol.setResizable(false);

		TableColumn typeCol = new TableColumn("类型");
		typeCol.setCellValueFactory(new PropertyValueFactory<DiskBlock, String>("typeP"));
		typeCol.setSortable(false);
		noCol.setMinWidth(60);
		typeCol.setResizable(false);

		TableColumn objCol = new TableColumn("内容");
		objCol.setCellValueFactory(new PropertyValueFactory<DiskBlock, String>("objectP"));
		objCol.setSortable(false);
		objCol.setMinWidth(130);
		objCol.setResizable(false);

		TableColumn nameCol = new TableColumn("文件名");
		nameCol.setCellValueFactory(new PropertyValueFactory<File, String>("fileNameP"));
		nameCol.setSortable(false);
		nameCol.setMinWidth(180);
		nameCol.setResizable(false);

		TableColumn flagCol = new TableColumn("打开方式");
		flagCol.setCellValueFactory(new PropertyValueFactory<File, String>("flagP"));
		flagCol.setSortable(false);
		flagCol.setResizable(false);
		flagCol.setMinWidth(180);

		TableColumn diskCol = new TableColumn("起始盘块号");
		diskCol.setCellValueFactory(new PropertyValueFactory<File, String>("diskNumP"));
		diskCol.setSortable(false);
		diskCol.setResizable(false);
		diskCol.setMinWidth(180);

		TableColumn diskNumCol = new TableColumn("磁盘块总数");
		diskNumCol.setCellValueFactory(new PropertyValueFactory<File, String>("lengthP"));
		diskNumCol.setMinWidth(180);
		diskNumCol.setSortable(false);
		diskNumCol.setResizable(false);

		TableColumn lengthCol = new TableColumn("文件总长度(B)");
		lengthCol.setCellValueFactory(new PropertyValueFactory<File, String>("sizeP"));
		lengthCol.setMinWidth(180);
		lengthCol.setSortable(false);
		lengthCol.setResizable(false);

		TableColumn pathCol = new TableColumn("路径");
		pathCol.setCellValueFactory(new PropertyValueFactory<File, String>("locationP"));
		pathCol.setSortable(false);
		pathCol.setMinWidth(500);
		pathCol.setResizable(false);


		blockTable.setItems(dataBlock);
		blockTable.getColumns().addAll(noCol, indexCol, typeCol, objCol);
		blockTable.setEditable(false);
		blockTable.setPrefWidth(352);

		openedTable.setItems(dataOpened);
		openedTable.getColumns().addAll(nameCol, flagCol, diskCol,diskNumCol, lengthCol,pathCol);
		openedTable.setPrefHeight(200);
	}

	private void initTreeView() {
		rootNode = new TreeItem<>("C:", new ImageView(FATUtil.DISK_IMG));
		rootNode.setExpanded(true);

		recentNode = rootNode;
		pathMap.put(fat.getPath("C:"), rootNode);

		treeView = new TreeView<String>(rootNode);
		treeView.setPrefWidth(255);
		treeView.setCellFactory((TreeView<String> p) -> new TextFieldTreeCellImpl());
		treeView.setStyle("-fx-background-color: #ffffff;" + "-fx-border-color: #d3d3d3;" + "-fx-border-width:0.5px;");

		for (Path path : fat.getPaths()) {
			System.out.println(path);
			if (path.hasParent() && path.getParent().getPathName().equals(rootNode.getValue())) {
				initTreeNode(path, rootNode);
			}
		}
		addIcon(fat.getBlockList(recentPath), recentPath);
	}

	private void initTreeNode(Path newPath, TreeItem<String> parentNode) {
		TreeItem<String> newNode = addNode(parentNode, newPath);
		if (newPath.hasChild()) {
			for (Path child : newPath.getChildren()) {
				initTreeNode(child, newNode);
			}
		}
	}

	private void addIcon(List<DiskBlock> bList, String path) {
		blockList = bList;
		int n = bList.size();
		icons = new Label[n];
		for (int i = 0; i < n; i++) {
			if (bList.get(i).getObject() instanceof Folder) {
				icons[i] = new Label(((Folder) bList.get(i).getObject()).getFolderName(),
						new ImageView(FATUtil.FOLDER_IMG));
			// 文件类型判断
			} else {
//				icons[i] = new Label(((File) bList.get(i).getObject()).getFileName(), new ImageView(FATUtil.FILE_IMG));
				File file = (File) bList.get(i).getObject();
				String typeName = file.getType();
				ImageView imageView;
				if ("txt".equals(typeName)) {
					imageView = new ImageView(FATUtil.FILE_TXT_IMG);
				} else if ("jpg".equals(typeName) ) {
					imageView = new ImageView(FATUtil.FILE_IMAGE_JPG);
					imageView.setFitWidth(64);
					imageView.setFitHeight(64);
				}else if ( "png".equals(typeName)) {
					imageView = new ImageView(FATUtil.FILE_IMAGE_PNG);
					imageView.setFitWidth(64);
					imageView.setFitHeight(64);
				}else if ( "doc".equals(typeName)) {
					imageView = new ImageView(FATUtil.FILE_IMAGE_DOC);
					imageView.setFitWidth(64);
					imageView.setFitHeight(64);
				}else if ( "docx".equals(typeName)) {
					imageView = new ImageView(FATUtil.FILE_IMAGE_DOCX);
					imageView.setFitWidth(64);
					imageView.setFitHeight(64);
				}else if ( "xlsx".equals(typeName)) {
					imageView = new ImageView(FATUtil.FILE_IMAGE_XLSX);
				}else if ( "pdf".equals(typeName)) {
					imageView = new ImageView(FATUtil.FILE_IMAGE_PDF);
					imageView.setFitWidth(64);
					imageView.setFitHeight(64);
				} else {
					// 设置默认图标
					imageView = new ImageView(FATUtil.DEFAULT_IMG);
				}
				icons[i] = new Label(file.getFileName(), imageView);

			}
			icons[i].setContentDisplay(ContentDisplay.TOP);
			icons[i].setWrapText(true);
			flowPane.getChildren().add(icons[i]);
			icons[i].setOnMouseEntered(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {
					((Label) event.getSource()).setStyle("-fx-background-color: #f0f8ff;");
				}
			});
			icons[i].setOnMouseExited(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {
					((Label) event.getSource()).setStyle("-fx-background-color: #f1dffa;");
				}
			});
			icons[i].setOnMouseClicked(new EventHandler<MouseEvent>() {

				@Override
				public void handle(MouseEvent event) {
					Label src = (Label) event.getSource();
					for (int j = 0; j < n; j++) {
						if (src == icons[j]) {
							index = j;
						}
					}
					DiskBlock thisBlock = blockList.get(index);
					if(thisBlock.getObject() instanceof File){
						if (event.getButton() == MouseButton.SECONDARY && event.getClickCount() == 1) {
							contextMenu3.show(src, event.getScreenX(), event.getScreenY());
						} else if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) {
							onOpen();
						} else {
							contextMenu3.hide();
						}
					}else{
						if (event.getButton() == MouseButton.SECONDARY && event.getClickCount() == 1) {
							contextMenu2.show(src, event.getScreenX(), event.getScreenY());
						} else if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) {
							onOpen();
						} else {
							contextMenu2.hide();
						}
					}
				}
			});
		}
	}

	private TreeItem<String> addNode(TreeItem<String> parentNode, Path newPath) {
		String pathName = newPath.getPathName();
		String value = pathName.substring(pathName.lastIndexOf('\\') + 1);
		TreeItem<String> newNode = new TreeItem<String>(value, new ImageView(FATUtil.TREE_NODE_IMG));
		newNode.setExpanded(true);
		pathMap.put(newPath, newNode);
		parentNode.getChildren().add(newNode);
		return newNode;
	}

	public void removeNode(TreeItem<String> recentNode, Path remPath) {
		recentNode.getChildren().remove(pathMap.get(remPath));
		pathMap.remove(remPath);
	}

	public TreeItem<String> getRecentNode() {
		return recentNode;
	}

	public void setRecentNode(TreeItem<String> recentNode) {
		this.recentNode = recentNode;
	}

//	public void refreshBlockTable() {
//		dataBlock = FXCollections.observableArrayList(fat.getDiskBlocks());
//		blockTable.setItems(dataBlock);
//		blockTable.refresh();
//	}

//	public void refreshOpenedTable() {
//		dataOpened = FXCollections.observableArrayList(fat.getOpenedFiles());
//		openedTable.setItems(dataOpened);
//		openedTable.refresh();
//	}

	private void onOpen() {
		// 打开文件 拿到对应的磁盘块
		DiskBlock thisBlock = blockList.get(index);
//		for (DiskBlock block : blockList) {
//			System.out.println(block);
//		}

		if (thisBlock.getObject() instanceof File) {
			if (fat.getOpenedFiles().size() < 5) {
				if (fat.isOpenedFile(thisBlock)) {
					Alert duplicate = new Alert(AlertType.ERROR, "文件已打开");
					duplicate.showAndWait();
				} else {
					fat.addOpenedFile(thisBlock);
					// 文件打开View展示区 显示文件的内容
					new FileView((File) thisBlock.getObject(), fat, thisBlock);
				}
			} else {
				Alert exceed = new Alert(AlertType.ERROR, "文件打开已到上限");
				exceed.showAndWait();
			}
		} else {
			Folder thisFolder = (Folder) thisBlock.getObject();
			String newPath = thisFolder.getLocation() + "\\" + thisFolder.getFolderName();
			flowPane.getChildren().removeAll(flowPane.getChildren());
			addIcon(fat.getBlockList(newPath), newPath);
			locField.setText(newPath);
			recentPath = newPath;
			recentNode = pathMap.get(thisFolder.getPath());
		}
	}

	private void onFlagOpen(int flag) {
		// 打开文件 拿到对应的磁盘块
		DiskBlock thisBlock = blockList.get(index);
//		for (DiskBlock block : blockList) {
//			System.out.println(block);
//		}

		if (thisBlock.getObject() instanceof File) {
			((File)(thisBlock.getObject())).setFlag(flag);
			if (fat.getOpenedFiles().size() < 5) {
				if (fat.isOpenedFile(thisBlock)) {
					Alert duplicate = new Alert(AlertType.ERROR, "文件已打开");
					duplicate.showAndWait();
				} else {
					fat.addOpenedFile(thisBlock);
					// 文件打开View展示区 显示文件的内容
					new FileView((File) thisBlock.getObject(), fat, thisBlock);
				}
			} else {
				Alert exceed = new Alert(AlertType.ERROR, "文件打开已到上限");
				exceed.showAndWait();
			}
		}
	}



	public final class TextFieldTreeCellImpl extends TreeCell<String> {

		private TextField textField;

		public TextFieldTreeCellImpl() {

			this.setOnMouseClicked(new EventHandler<MouseEvent>() {
				@Override
				public void handle(MouseEvent event) {
					if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 1) {
						if (getTreeItem() != null) {
							String pathName = null;
							for (Map.Entry<Path, TreeItem<String>> entry : pathMap.entrySet()) {
								if (getTreeItem() == entry.getValue()) {
									pathName = entry.getKey().getPathName();
									break;
								}
							}
							List<DiskBlock> fats = fat.getBlockList(pathName);
							flowPane.getChildren().removeAll(flowPane.getChildren());
							addIcon(fats, pathName);
							recentPath = pathName;
							recentNode = getTreeItem();
							locField.setText(recentPath);
						}
					}
				}
			});
		}

		@Override
		public void startEdit() {
			super.startEdit();

			if (textField == null) {
				createTextField();
			}
			setText(null);
			setGraphic(textField);
			textField.selectAll();
		}

		@Override
		public void cancelEdit() {
			super.cancelEdit();
			setText((String) getItem());
			setGraphic(getTreeItem().getGraphic());
		}

		@Override
		public void updateItem(String item, boolean empty) {
			super.updateItem(item, empty);

			if (empty) {
				setText(null);
				setGraphic(null);
			} else {
				if (isEditing()) {
					if (textField != null) {
						textField.setText(getString());
					}
					setText(null);
					setGraphic(textField);
				} else {
					setText(getString());
					setGraphic(getTreeItem().getGraphic());
				}
			}
		}

		private void createTextField() {
			textField = new TextField(getString());
			textField.setOnKeyReleased((KeyEvent t) -> {
				if (t.getCode() == KeyCode.ENTER) {
					commitEdit(textField.getText());
				} else if (t.getCode() == KeyCode.ESCAPE) {
					cancelEdit();
				}
			});

		}

		private String getString() {
			return getItem() == null ? "" : getItem().toString();
		}

	}

}
